home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / UUPC11QS.ARJ / UUCP.C < prev    next >
C/C++ Source or Header  |  1991-10-21  |  23KB  |  557 lines

  1. /*******************************************************
  2. *@(#) uucp.c  UUCP lookalike for IBM PC.
  3. *           H.A.E.Broomhall         1991/02/08
  4. *           Hacked for UUPC/extended 1.09c
  5. *           Modified for UUPC/extended 1.10a by ahd   4/27/91
  6. *           Support for UUX by Mitch Mitchell 9/26/91
  7. *******************************************************/
  8.  
  9. /*--------------------------------------------------------------------*/
  10. /*                        system include files                        */
  11. /*--------------------------------------------------------------------*/
  12.  
  13. #include  <ctype.h>
  14. #include  <direct.h>
  15. #include  <fcntl.h>
  16. #include  <io.h>
  17. #include  <stdio.h>
  18. #include  <stdlib.h>
  19. #include  <string.h>
  20. #include  <sys/types.h>
  21. #include  <sys/stat.h>
  22.  
  23. /*--------------------------------------------------------------------*/
  24. /*                    UUPC/extended include files                     */
  25. /*--------------------------------------------------------------------*/
  26.  
  27. #include  "lib.h"
  28. #include  "expath.h"
  29. #include  "getopt.h"
  30. #include  "getseq.h"
  31. #include  "hlib.h"
  32. #include  "hostable.h"
  33. #include  "import.h"
  34. #include  "ndir.h"
  35. #include  "security.h"
  36. #include  "timestmp.h"
  37.  
  38. /*--------------------------------------------------------------------*/
  39. /*                          Global variables                          */
  40. /*--------------------------------------------------------------------*/
  41.  
  42. static boolean       spool_flag = FALSE;
  43. static char          spool_file[FILENAME_MAX]; /* alt spool file name */
  44. static boolean       dir_flag = TRUE;
  45. static boolean       xeqt_flag = TRUE;    /* Triggered by -r option */
  46. static char          grade = 'N';         /* Default grade of service */
  47. static boolean       mail_me = FALSE;     /* changes with -m */
  48. static boolean       mail_them = FALSE;   /* changes with -n */
  49. static char  remote_user[10];             /* user to mail with -n */
  50. static char  *destn_file;
  51. static char  flags[16];
  52.  
  53. currentfile();
  54.  
  55. /*--------------------------------------------------------------------*/
  56. /*    u s a g e                                                       */
  57. /*                                                                    */
  58. /*    Report flags used by program                                    */
  59. /*--------------------------------------------------------------------*/
  60.  
  61. static         void    usage(void)
  62. {
  63.       fprintf(stderr, "Usage: uucp\t[-c|-C] [-d|-f] [-gGRADE] [-j] [-m] [-nUSER] [-r] [-sFILE]\\\n\
  64. \t\t[-xDEBUG_LEVEL] source-files destination-file\n");
  65. }
  66.  
  67. static         int     cp(char *from, char *to)
  68. {
  69.       int         fd_from, fd_to;
  70.       int         nr, nw;
  71.       char        buf[BUFSIZ];            /* faster if we alloc a big buffer */
  72.  
  73.       /* This would be even faster if we determined that both files
  74.          were on the same device, dos >= 3.0, and used the dos move
  75.          function */
  76.       if ((fd_from = open(from, O_RDONLY | O_BINARY)) == -1)
  77.          return(1);        /* failed */
  78.       /* what if the to is a directory? */
  79.       /* possible with local source & dest uucp */
  80.       if ((fd_to = open(to, O_CREAT | O_BINARY | O_WRONLY, S_IWRITE | S_IREAD)) == -1) {
  81.          close(fd_from);
  82.          return(1);        /* failed */
  83.          /* NOTE - this assumes all the required directories exist!  */
  84.       }
  85.       while  ((nr = read(fd_from, buf, sizeof buf)) > 0 &&
  86.          (nw = write(fd_to, buf, nr)) == nr)
  87.          ;
  88.       close(fd_to);
  89.       close(fd_from);
  90.       if (nr != 0 || nw == -1)
  91.          return(1);        /* failed in copy */
  92.       return(0);
  93. }
  94.  
  95. /*--------------------------------------------------------------------*/
  96. /*    s p l i t _ p a t h                                             */
  97. /*                                                                    */
  98. /*    split_path splits a path into 3 components.                     */
  99. /*    1)  The system next in line                                     */
  100. /*    2)  Any intermediate systems as a bang path                     */
  101. /*    3)  The actual file name/path                                   */
  102. /*                                                                    */
  103. /*    It tries to be a little clever with idiots, in recognizing      */
  104. /*    system=this machine                                             */
  105. /*--------------------------------------------------------------------*/
  106.  
  107. static         void    split_path(char *path,
  108.                                   char *system,
  109.                                   char *inter,
  110.                                   char *file)
  111. {
  112.       char    *p_left, *p_right, *p;
  113.  
  114.       *system = *inter = *file = '\0';    /* init to nothing */
  115.       for (p = path;; p = p_left + 1)  {
  116.          p_left = strchr(p, '!');         /* look for the first bang */
  117.          if (p_left == NULL)  {           /* not a remote path */
  118.             strcpy(file, p);              /* so just return filename */
  119.             return;
  120.          }
  121.          /* now check if the system was in fact us.
  122.        If so strip it and restart */
  123.          if (equaln(nodename, p, p_left - p) && (nodename[p_left - p] == '\0'))
  124.             continue;
  125.  
  126.          p_right = strrchr(p, '!');      /* look for the last bang */
  127.          strcpy(file, p_right + 1);      /* and thats our filename */
  128.          strncpy(system, p, p_left - p); /* and we have a system thats not us */
  129.          system[p_left - p] = '\0';
  130.          /* now see if there is an intermediate path */
  131.          if (p_left != p_right)  {        /* yup - there is */
  132.             strncpy(inter, p_left + 1, p_right - p_left - 1);
  133.             inter[p_right - p_left - 1] = '\0';
  134.          }
  135.          return;                 /* and we're done */
  136.       }        /* never get here :-)  */
  137. }
  138.  
  139. /*--------------------------------------------------------------------*/
  140. /*    d o _ u u x                                                     */
  141. /*                                                                    */
  142. /*    Generate & execute UUX command                                  */
  143. /*--------------------------------------------------------------------*/
  144.  
  145. int   do_uux(char *remote,
  146.              char *src_syst,
  147.              char *src_file,
  148.              char *dest_syst,
  149.              char *dest_inter,
  150.              char *dest_file)
  151. {
  152.       char        xcmd[BUFSIZ];        /* buffer for assembling the UUX command */
  153.       char        *ex_flg;
  154.  
  155.       /* first - lets get the basic command */
  156.       ex_flg = xeqt_flag ? "" : "-r";
  157.       sprintf(xcmd, "uux -C %s %s!uucp -C ", ex_flg, remote);
  158.       /* but what about mailing the guy? */
  159.       /* now we sort out the source name */
  160.       if ((*src_syst == '\0') || equal(src_syst, nodename))
  161.          sprintf(xcmd + strlen(xcmd), " %s ", src_file);
  162.       else  {
  163.          if (!equal(remote, src_syst))
  164.             sprintf(xcmd + strlen(xcmd), " (%s!%s) ", src_syst, src_file);
  165.          else
  166.             sprintf(xcmd + strlen(xcmd), " (%s) ", src_file);
  167.       }
  168.       /* now to do the destination name */
  169.       if (*dest_inter != '\0')  {
  170.          if (*dest_syst != '\0')
  171.             sprintf(xcmd + strlen(xcmd), " (%s!%s!%s) ", dest_syst, dest_inter, dest_file);
  172.          else
  173.             sprintf(xcmd + strlen(xcmd), " (%s!%s) ", dest_inter, dest_file);
  174.       }
  175.       else  {
  176.          if ((*dest_syst == '\0') || equal(dest_syst, nodename))
  177.             sprintf(xcmd + strlen(xcmd), " (%s!%s) ", nodename, dest_file);
  178.       }
  179.       printmsg(2, "xcmd: %s", xcmd);
  180.       /* OK - GO! */
  181.       system(xcmd);
  182.       return(1);
  183. }
  184.  
  185. /*--------------------------------------------------------------------*/
  186. /*    d o _ c o p y                                                   */
  187. /*                                                                    */
  188. /*    At this point only one of the systems can be remote and only    */
  189. /*    1 hop away.  All the rest have been filtered out                */
  190. /*--------------------------------------------------------------------*/
  191.  
  192. int   do_copy(char *src_syst,
  193.               char *src_file,
  194.               char *dest_syst,
  195.               char *dest_file)
  196. {
  197.       char        *p, *p1;
  198.       boolean wild_flag = FALSE;
  199.       boolean write_flag;
  200.       char        tmfile[15];       /* Unix style name for c file */
  201.       char        idfile[15];       /* Unix style name for data file copy */
  202.       char        work[66];            /* temp area for filename hacking */
  203.       char        search_file[66];
  204.       char        source_path[66];
  205.       char        icfilename[66]; /* our hacked c file path */
  206.       char        idfilename[66]; /* our hacked d file path */
  207.  
  208.       struct  stat    statbuf;
  209.       DIR *dirp = NULL;
  210.       struct direct *dp;
  211.       char subseq = 'A';
  212.  
  213.       long    int     sequence;
  214.       char    *remote_syst;   /* Non-local system in copy            */
  215.       char    *sequence_s;
  216.       FILE        *cfile;
  217.       static  char    *spool_fmt = SPOOLFMT;
  218.  
  219.       sequence = getseq();
  220.       sequence_s = JobNumber( sequence );
  221.       remote_syst =  equal(src_syst, nodename) ? dest_syst : src_syst;
  222.       sprintf(tmfile, spool_fmt, 'C', remote_syst, grade, sequence_s);
  223.       importpath(work, tmfile, remote_syst);
  224.       mkfilename(icfilename, spooldir, work);
  225.  
  226.       if (!equal(src_syst, nodename))  {
  227.          if (expand_path(dest_file, NULL, homedir, NULL) == NULL)
  228.             exit(1);
  229.          p  = src_file;
  230.          while (*p) {
  231.             if (*p ==  '\\')
  232.                *p = '/';
  233.             p++;
  234.          }
  235.          printmsg(1, "uucp - from \"%s\" - control = %s", src_syst,
  236.                   tmfile);
  237.          if ((cfile = FOPEN(icfilename, "a", 't')) == NULL)  {
  238.             printerr( icfilename );
  239.             fprintf(stderr, "uucp: cannot append to %s\n", icfilename);
  240.             panic();
  241.          }
  242.          fprintf(cfile, "R %s %s %s -%s %s 0777 %s\n", src_file, dest_file,
  243.                mailbox, flags, *spool_file ? spool_file : "dummy", remote_user);
  244.          fclose(cfile);
  245.          return(1);
  246.       }
  247.       else if (!equal(dest_syst, nodename))  {
  248.          printmsg(1,"uucp - spool %s - mkdir %s - execute %s",
  249.                 spool_flag ? "on" : "off",
  250.                   dir_flag ? "on" : "off", xeqt_flag ? "do" : "don't");
  251.          printmsg(1,"     - dest m/c = %s  sequence = %ld  control = %s",
  252.                   dest_syst, sequence, tmfile);
  253.          if (expand_path(src_file, NULL, homedir, NULL) == NULL)
  254.             exit(1);
  255.          p  = dest_file;
  256.          while (*p) {
  257.             if (*p ==  '\\')
  258.                *p = '/';
  259.             p++;
  260.          }
  261.          if (strcspn(src_file, "*?") == strlen(src_file))  {
  262.             wild_flag = FALSE;
  263.             if (stat(src_file, &statbuf) != 0)  {
  264.                printerr( src_file );
  265.                exit(1);
  266.             }
  267.             if (statbuf.st_mode & S_IFDIR)  {
  268.                printf("uucp - directory name \"%s\" illegal\n",
  269.                        src_file );
  270.                exit(1);
  271.             }
  272.          }
  273.          else  {
  274.             wild_flag = TRUE;
  275.             strcpy(source_path, src_file);
  276.             p = strrchr(source_path, '/');
  277.             strcpy(search_file, p+1);
  278.             *++p = '\0';
  279.  
  280.             dirp = opendirx(source_path,search_file);
  281.             if (dirp == NULL)
  282.             {
  283.                printf("uucp - unable to open directory %s\n",source_path);
  284.                exit(1);
  285.             } /* if */
  286.  
  287.             if ((dp = readdir(dirp)) == nil(struct direct))
  288.             {
  289.                printf("uucp - can't find any file %s\n", search_file);
  290.                exit(1);
  291.             }
  292.          }
  293.          write_flag = TRUE;
  294.          while (write_flag)  {
  295.             if (wild_flag)  {
  296.                strcpy(src_file, source_path);
  297.                p = strchr(src_file, '\0');
  298.                p1 = dp->d_name;
  299.                while (*p1)
  300.                   *p++ = (char)tolower(*p1++);
  301.                *p = '\0';
  302.                printf("Queueing file %s for %s!%s\n", src_file, dest_syst,
  303.                         dest_file);
  304.             }
  305.             if (spool_flag)  {
  306.                sprintf(idfile , spool_fmt, 'D', nodename, (char) subseq++,
  307.                            sequence_s);
  308.                importpath(work, idfile, remote_syst);
  309.                mkfilename(idfilename, spooldir, work);
  310.                /* Do we need a MKDIR here for the system? */
  311.                if (cp(src_file, idfilename) != 0)  {
  312.                   printmsg(0, "copy \"%s\" to \"%s\" failed",
  313.                      src_file, idfilename);           /* copy data */
  314.                   closedir( dirp );
  315.                   exit(1);
  316.                }
  317.             }
  318.             else
  319.                strcpy(idfile, "D.0");
  320.             if ((cfile = FOPEN(icfilename, "a", 't')) == NULL)  {
  321.                printerr( icfilename );
  322.                printf("uucp: cannot append to %s\n", icfilename);
  323.                if (dirp != NULL )
  324.                   closedir( dirp );
  325.                exit(1);
  326.             }
  327.             fprintf(cfile, "S %s %s %s -%s %s 0666 %s\n", src_file, dest_file,
  328.                      mailbox, flags, idfile, remote_user);
  329.             fclose(cfile);
  330.             if (wild_flag)  {
  331.                dp = readdir(dirp);
  332.                if ( dp == NULL )
  333.                   write_flag = FALSE;
  334.             }
  335.             else
  336.                write_flag = FALSE;
  337.          }
  338.          if (dirp != NULL )
  339.             closedir( dirp );
  340.          return(1);
  341.       }
  342.       else  {
  343.          if (expand_path(src_file, NULL, homedir, NULL) == NULL)
  344.             exit(1);
  345.          if (expand_path(dest_file, NULL, homedir, NULL) == NULL)
  346.             exit(1);
  347.          if (strcmp(src_file, dest_file) == 0)  {
  348.             fprintf(stderr, "%s %s - same file; can't copy\n",
  349.                   src_file, dest_file);
  350.             exit(1);
  351.          }
  352.          cp(src_file, dest_file);
  353.          return(1);
  354.       }
  355. }
  356.  
  357. /*--------------------------------------------------------------------*/
  358. /*    m a i n                                                         */
  359. /*                                                                    */
  360. /*    main program, of course                                         */
  361. /*--------------------------------------------------------------------*/
  362.  
  363. void  main(int argc, char *argv[])
  364. {
  365.       int         i;
  366.       int         option;
  367. /*
  368.       boolean s_remote = FALSE;
  369.       boolean d_remote = FALSE;
  370. */
  371.       boolean j_flag = FALSE;
  372.       char        src_system[100], dest_system[100];
  373.       char        src_inter[100],  dest_inter[100];
  374.       char        src_file[FILENAME_MAX],   dest_file[FILENAME_MAX];
  375.  
  376. /*--------------------------------------------------------------------*/
  377. /*                             Initialize                             */
  378. /*--------------------------------------------------------------------*/
  379.  
  380.       debuglevel = 0;
  381.  
  382.       banner( argv );
  383.       if (!configure(B_UUCP))
  384.          exit(1);
  385.  
  386. /*--------------------------------------------------------------------*/
  387. /*                        Process option flags                        */
  388. /*--------------------------------------------------------------------*/
  389.  
  390.       while ((option = getopt(argc, argv, "Ccdfg:jmn:rs:x:")) != EOF)  {
  391.          switch(option)  {
  392.             case 'c':               /* don't spool */
  393.                spool_flag = FALSE;
  394.                break;
  395.             case 'C':               /* force spool */
  396.                spool_flag = TRUE;
  397.                break;
  398.             case 'd':               /* make directories */
  399.                dir_flag = TRUE;
  400.                break;
  401.             case 'e':               /* send uucp command to sys */
  402.                /* This one is in Sams but nowhere else - I'm ignoring it */
  403.                break;
  404.             case 'f':               /* don't make directories */
  405.                dir_flag = FALSE;
  406.                break;
  407.             case 'g':               /* set grade of transfer */
  408.                grade = *optarg;
  409.                break;
  410.             case 'j':               /* output job id to stdout */
  411.                j_flag = TRUE;
  412.                break;
  413.             case 'm':               /* send mail when copy completed */
  414.                mail_me = TRUE;
  415.                break;
  416.             case 'n':               /* notify remote user file was sent */
  417.                mail_them = TRUE;
  418.                sprintf(remote_user, "%.8s", optarg);
  419.                break;
  420.             case 'r':               /* queue job only */
  421.                xeqt_flag = FALSE;
  422.                break;
  423.             case 's':               /* report status of transfer to file */
  424.                strcpy( spool_file, optarg);
  425.                expand_path( spool_file, NULL, pubdir , NULL);
  426.                break;
  427.             case 'x':               /* set debug level */
  428.                debuglevel = atoi(optarg);
  429.                break;
  430.             default:
  431.                usage();
  432.                exit(1);
  433.                break;
  434.          }
  435.       }
  436.       flags[0] = (char)(dir_flag ? 'd' : 'f');
  437.       flags[1] = (char)(spool_flag ? 'C' : 'c');
  438.       i = 2;
  439.       if (mail_them)
  440.          flags[i++] = 'n';
  441.       flags[i] = '\0';
  442.       if (remote_user[0] == '\0')
  443.          strcpy(remote_user, mailbox);
  444.       if (argc - optind < 2)  {
  445.          usage();
  446.          exit(1);
  447.       }
  448. /*--------------------------------------------------------------------*/
  449. /*       Now - posibilities:                                          */
  450. /*       Sources - 1 or more, local or 1 hop away (NOT > 1 hop!)      */
  451. /*       Dest    - normal cp rules, single only, local, 1 hop or >1   */
  452. /*                 hop                                                */
  453. /*       Wildcards possible on sources.                               */
  454. /*                                                                    */
  455. /*    Actions depend on these - so we need to split the pathnames     */
  456. /*    for more info.                                                  */
  457. /*--------------------------------------------------------------------*/
  458.  
  459.       split_path(argv[argc - 1], dest_system, dest_inter, dest_file);
  460.  
  461. /*--------------------------------------------------------------------*/
  462. /*        OK - we have a destination system - do we know him?         */
  463. /*--------------------------------------------------------------------*/
  464.  
  465.       if (*dest_system != '\0')  {
  466.          if (checkreal(dest_system) == BADHOST)  {
  467.             fprintf(stderr, "uucp - bad system: %s\n", dest_system);
  468.             exit(1);
  469.          }
  470.       }
  471.       else        /* make sure we have a system name for destination */
  472.          strcpy(dest_system, nodename);
  473.       printmsg(9, "destination: system \"%s\", inter \"%s\", file \"%s\"",
  474.             dest_system, dest_inter, dest_file);
  475.  
  476. /*--------------------------------------------------------------------*/
  477. /*    Now - if there is more than 1 source then normal cp rules,      */
  478. /*          i.e. dest must be a directory                             */
  479. /*--------------------------------------------------------------------*/
  480.  
  481.       if (argc - optind > 2)
  482.          strcat(dest_file, "/");
  483.       destn_file = argv[argc - 1];
  484.       for (i = optind; i < (argc - 1); i++)  {
  485.          split_path(argv[i], src_system, src_inter, src_file);
  486.  
  487. /*--------------------------------------------------------------------*/
  488. /*            We need to winnow out various combinations -            */
  489. /*                        so lets get at them                         */
  490. /*                                                                    */
  491. /*                   Do we know the source system?                    */
  492. /*--------------------------------------------------------------------*/
  493.  
  494.          if (*src_system != '\0')  {
  495.             if (checkreal(src_system) == BADHOST)  {
  496.                fprintf(stderr, "uucp - bad system %s\n", src_system);
  497.                exit(1);
  498.             }
  499.          }
  500.  
  501. /*--------------------------------------------------------------------*/
  502. /*                    Source can't be >1 hop away                     */
  503. /*--------------------------------------------------------------------*/
  504.  
  505.          if (*src_inter != '\0')  {
  506.             fprintf(stderr, "uucp - illegal syntax %s\n", argv[i]);
  507.             exit(1);
  508.          }
  509.  
  510. /*--------------------------------------------------------------------*/
  511. /*        if source is remote AND wildcarded then we need uux         */
  512. /*--------------------------------------------------------------------*/
  513.  
  514.          if ((*src_system != '\0') && (strcspn(src_file, "*?[") < strlen(src_file)))  {
  515.             do_uux(src_system, src_system, src_file, dest_system, dest_inter, dest_file);
  516.             continue;
  517.          }
  518.  
  519. /*--------------------------------------------------------------------*/
  520. /*            if dest requires forwarding then we need uux            */
  521. /*--------------------------------------------------------------------*/
  522.  
  523.          if (*dest_inter != '\0')  {
  524.             do_uux(dest_system, src_system, src_file, "", dest_inter, dest_file);
  525.             continue;
  526.          }
  527.  
  528. /*--------------------------------------------------------------------*/
  529. /*         if both source & dest are remote then we need uux          */
  530. /*--------------------------------------------------------------------*/
  531.  
  532.          if ((*src_system != '\0') && (!equal(src_system, nodename)) &&
  533.                (*dest_system != '\0') && (!equal(dest_system, nodename)))  {
  534.             do_uux(dest_system, src_system, src_file, "", dest_inter, dest_file);
  535.             continue;
  536.          }
  537. /*--------------------------------------------------------------------*/
  538. /*          We have left 3 options:                                   */
  539. /*          1) src remote (non-wild) & dest local                     */
  540. /*          2) src local & dest remote 1 hop                          */
  541. /*          3) src & dest both local                                  */
  542. /*                                                                    */
  543. /*               fill up the src system if not already                */
  544. /*--------------------------------------------------------------------*/
  545.          if (*src_system == '\0')
  546.             strcpy(src_system, nodename);
  547.          printmsg(4, "source: system \"%s\", file \"%s\"", src_system,
  548.                      src_file);
  549.          do_copy(src_system, src_file, dest_system, dest_file);
  550.       }
  551.       if (xeqt_flag)
  552.          printmsg(1, "Call uucico");
  553.       if (j_flag)
  554.          printmsg(1,"j_flag");
  555.       exit(0);
  556. }
  557.